package com.cardone.platform.authority.dao;

import java.util.List;
import java.util.UUID;

import lombok.Getter;
import lombok.Setter;

import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang3.StringUtils;

import com.cardone.common.dto.PaginationDto;
import com.cardone.context.Attributes;
import com.cardone.context.ContextHolder;
import com.cardone.context.DictionaryException;
import com.cardone.persistent.builder.Model;
import com.cardone.persistent.builder.ModelArgs;
import com.cardone.persistent.builder.ModelUtils;
import com.cardone.persistent.support.JdbcTemplateSupport;
import com.cardone.persistent.support.PaginationArgs;
import com.cardone.platform.authority.dto.PermissionOrgDto;

/**
 * 许可与组织
 *
 * @author yaohaitao
 *
 */
@Getter
@Setter
public class PermissionOrgJdbcDao implements PermissionOrgDao {
	/**
	 * 代码名称集合
	 */
	private String[] codeNames = { Attributes.code.name() };

	/**
	 * 标识名称集合
	 */
	private String[] idNames = { Attributes.id.name() };

	/**
	 * 更新名称集合
	 */
	private String[] updateNames = { Attributes.parentId.name(), Attributes.typeId.name(), Attributes.code.name(), Attributes.name.name(), Attributes.value.name(), Attributes.remark.name() };

	@Override
	public int deleteByIds(final PermissionOrgDto deletePermissionOrg) {
		final Model model = ModelUtils.newModel();

		if (MapUtils.isNotEmpty(deletePermissionOrg.getAttrs())) {
			model.putAll(deletePermissionOrg.getAttrs());
		}

		model.put(Attributes.ids.name(), deletePermissionOrg.getIds());

		model.putTrue(Model.Keys.whereAndBetween.stringValue(), Attributes.sysdate.name());

		return ContextHolder.getBean(JdbcTemplateSupport.class).update(SqlIds.deleteByIds.id(), model);
	}

	@Override
	public <P> P findByCodeOrId(final Class<P> mappedClass, final PermissionOrgDto findPermissionOrg) {
		String[] whereAndEqProperties;

		if (StringUtils.isBlank(findPermissionOrg.getId())) {
			whereAndEqProperties = this.codeNames;
		} else {
			whereAndEqProperties = this.idNames;
		}

		final Model model = ModelUtils.newModel(new ModelArgs(findPermissionOrg, whereAndEqProperties));

		if (MapUtils.isNotEmpty(findPermissionOrg.getAttrs())) {
			model.putAll(findPermissionOrg.getAttrs());
		}

		model.putTrue(Model.Keys.whereAndBetween.stringValue(), Attributes.sysdate.name());

		return ContextHolder.getBean(JdbcTemplateSupport.class).find(mappedClass, SqlIds.findByCode.id(), model);
	}

	@Override
	public <P> P findById(final Class<P> mappedClass, final PermissionOrgDto findPermissionOrg) {
		final String[] whereAndEqProperties = this.idNames;

		final Model model = ModelUtils.newModel(new ModelArgs(findPermissionOrg, whereAndEqProperties).setIsSimple(true));

		if (MapUtils.isNotEmpty(findPermissionOrg.getAttrs())) {
			model.putAll(findPermissionOrg.getAttrs());
		}

		return ContextHolder.getBean(JdbcTemplateSupport.class).find(mappedClass, SqlIds.findById.id(), model);
	}

	@Override
	public <P> List<P> findList(final Class<P> mappedClass) {
		return ContextHolder.getBean(JdbcTemplateSupport.class).findList(mappedClass, SqlIds.find.id(), null);
	}

	@Override
	public <P> List<P> findListByLikeCode(final Class<P> mappedClass, final PermissionOrgDto findListPermissionOrg) {
		final Model model = ModelUtils.newModel(new ModelArgs(findListPermissionOrg).setIsSimple(true));

		if (MapUtils.isNotEmpty(findListPermissionOrg.getAttrs())) {
			model.putAll(findListPermissionOrg.getAttrs());
		}

		return ContextHolder.getBean(JdbcTemplateSupport.class).findList(mappedClass, SqlIds.findByLikeCode.id(), model);
	}

	@Override
	public int insertByCode(final PermissionOrgDto insertPermissionOrg) {
		if (StringUtils.isBlank(insertPermissionOrg.getId())) {
			insertPermissionOrg.setId(UUID.randomUUID().toString());
		}

		final Model model = ModelUtils.newModel(new ModelArgs(Model.Keys.insert.stringValue(), insertPermissionOrg));

		if (MapUtils.isNotEmpty(insertPermissionOrg.getAttrs())) {
			model.putAll(insertPermissionOrg.getAttrs());
		}

		model.putTrue(Model.Keys.whereAndBetween.stringValue(), Attributes.sysdate.name());

		return ContextHolder.getBean(JdbcTemplateSupport.class).update(SqlIds.insertByCode.id(), model);
	}

	@Override
	public int insertByNotExistsCode(final PermissionOrgDto insertPermissionOrg) {
		String[] whereAndEqProperties;

		if (StringUtils.isBlank(insertPermissionOrg.getId())) {
			insertPermissionOrg.setId(UUID.randomUUID().toString());

			whereAndEqProperties = this.codeNames;
		} else {
			whereAndEqProperties = this.idNames;
		}

		final Model model = ModelUtils.newModel(new ModelArgs(insertPermissionOrg, whereAndEqProperties), new ModelArgs(Model.Keys.insert.stringValue(), insertPermissionOrg));

		if (MapUtils.isNotEmpty(insertPermissionOrg.getAttrs())) {
			model.putAll(insertPermissionOrg.getAttrs());
		}

		model.putTrue(Model.Keys.whereAndBetween.stringValue(), Attributes.sysdate.name());

		return ContextHolder.getBean(JdbcTemplateSupport.class).update(SqlIds.insertByNotExistsCode.id(), model);
	}

	@Override
	public <P> PaginationDto<P> paginationByLikeCode(final Class<P> mappedClass, final PermissionOrgDto paginationPermissionOrg) {
		final Model model = ModelUtils.newModel(new ModelArgs(paginationPermissionOrg).setIsSimple(true));

		if (MapUtils.isNotEmpty(paginationPermissionOrg.getAttrs())) {
			model.putAll(paginationPermissionOrg.getAttrs());
		}

		return ContextHolder.getBean(JdbcTemplateSupport.class).pagination(mappedClass, new PaginationArgs(SqlIds.readByLikeCode.id(), SqlIds.findByLikeCode.id(), paginationPermissionOrg), model);
	}

	@Override
	public Integer readByCodeNqIdForCount(final PermissionOrgDto readPermissionOrg) {
		final Model model = ModelUtils.newModel(new ModelArgs(readPermissionOrg, this.codeNames));

		if (MapUtils.isNotEmpty(readPermissionOrg.getAttrs())) {
			model.putAll(readPermissionOrg.getAttrs());
		}

		if (StringUtils.isNotBlank(readPermissionOrg.getId())) {
			ModelUtils.put(model, new ModelArgs(Model.Keys.whereAndNq.stringValue(), readPermissionOrg, this.idNames));
		}

		model.putTrue(Model.Keys.whereAndBetween.stringValue(), Attributes.sysdate.name());

		return ContextHolder.getBean(JdbcTemplateSupport.class).read(Integer.class, SqlIds.readByCode.id(), model);
	}

	@Override
	public <P> P saveByIdOrCode(final Class<P> mappedClass, final PermissionOrgDto savePermissionOrg) {
		final int insertCount = this.insertByNotExistsCode(savePermissionOrg);

		if (insertCount < 1) {
			this.updateByCode(savePermissionOrg);
		}

		return this.findByCodeOrId(mappedClass, savePermissionOrg);
	}

	@Override
	public int updateByCode(final PermissionOrgDto updatePermissionOrg) {
		String[] whereAndEqProperties;

		if (StringUtils.isBlank(updatePermissionOrg.getId())) {
			whereAndEqProperties = this.codeNames;
		} else {
			whereAndEqProperties = this.idNames;
		}

		final String[] updateProperties = this.updateNames;

		final Model model = ModelUtils.newModel(new ModelArgs(Model.Keys.update.stringValue(), updatePermissionOrg, updateProperties), new ModelArgs(updatePermissionOrg, whereAndEqProperties));

		final int updateCount = ContextHolder.getBean(JdbcTemplateSupport.class).update(SqlIds.updateByCode.id(), model);

		if (updateCount < 1) {
			throw new DictionaryException("没有更新到数据").setTypeCode("update").setCode("not");
		} else if (updateCount > 1) {
			throw new DictionaryException("更新到多个数据").setTypeCode("update").setCode("multiple");
		}

		return updateCount;
	}
}